﻿using Xejen.Ipc.Framework;
using Xejen.Ipc.Framework.Flows;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Xejen.Ipc.Framework.Extensions
{
    /// <summary>
    /// 表示流程构建器
    /// </summary>
    /// <creator>marc</creator>
    internal class FlowBuilder<TData> : IFlowBuilder<TData>
        where TData : new()
    {
        private readonly IIpcHost _host;
        /// <inheritdoc/>
        public Func<IBuilderFactory<TData>, IFlow<TData>> Body { get; set; }

        /// <inheritdoc/>
        public Action<FlowEventArgs<TData>> Started { get; set; }
        /// <inheritdoc/>
        public Action<FlowEventArgs<TData>> Paused { get; set; }
        /// <inheritdoc/>
        public Action<FlowEventArgs<TData>> Resumed { get; set; }
        /// <inheritdoc/>
        public Action<FlowEventArgs<TData>> Stopped { get; set; }
        /// <inheritdoc/>
        public Action<FlowEventArgs<TData>> CycleCompleted { get; set; }
        /// <inheritdoc/>
        public Action<ScanIntervalExceededEventArgs<TData>> ScanIntervalExceeded { get; set; }
        /// <inheritdoc/>
        public Action<ErrorEventArgs<TData>> Error { get; set; }

        /// <inheritdoc/>
        public Action<IFlow<TData>> Execution { get; set; }

        /// <inheritdoc cref="FlowBuilder{TData}"/>
        public FlowBuilder(IIpcHost host)
        {
            _host = host;
        }

        /// <inheritdoc/>
        public IFlow<TData> CreateFlow()
        {
            IFlow<TData> flow = _host.CreateFlowWithFactory<TData>(Body);
            flow.Started += (sender, args) => { Started?.Invoke(args); };
            flow.Paused += (sender, args) => { Paused?.Invoke(args); };
            flow.Resumed += (sender, args) => { Resumed?.Invoke(args); };
            flow.Stopped += (sender, args) => { Stopped?.Invoke(args); };
            flow.CycleCompleted += (sender, args) => { CycleCompleted?.Invoke(args); };
            flow.ScanIntervalExceeded += (sender, args) => { ScanIntervalExceeded?.Invoke(args); };
            flow.Error += (sender, args) => { Error?.Invoke(args); };

            Execution?.Invoke(flow);

            return flow;
        }
    }
}
